package org.xtremeobjects.domain.model.expression.el;

import java.beans.FeatureDescriptor;
import java.lang.reflect.Method;
import java.util.Iterator;

import javax.el.ELContext;
import javax.el.ELResolver;
import javax.el.PropertyNotWritableException;

public class MethodResolver extends ELResolver {
	public MethodResolver() {
	}

	@Override
	public Method getValue(ELContext context, Object base, Object prop) {
		return resolveMethod(context, base.getClass(), prop.toString());
	}
	
	private Method resolveMethod( ELContext context, Class<?> clazz, String methodName ) {
		Method method = null;
		if(clazz==null) {
			context.setPropertyResolved(false);
			return null;
		}
		
		try {
			method = clazz.getMethod(methodName);
			context.setPropertyResolved(true);
		} catch (SecurityException e) {
		} catch (NoSuchMethodException e) {
			try {
				method = clazz.getDeclaredMethod(methodName);
				method.setAccessible(true);
				context.setPropertyResolved(true);
			} catch (NoSuchMethodException e1) {
				return resolveMethod(context, clazz.getSuperclass(), methodName);
			}
		}
		/*
		if (method.getDeclaringClass().isInstance(base) && method.getName().equals(prop.toString())) {
			return method;
		}
		/**/
		return method;
		
	}

	@Override
	public void setValue(ELContext context, Object base, Object property, Object value) {
		throw new PropertyNotWritableException();
	}

	@Override
	public Class<?> getCommonPropertyType(ELContext context, Object base) {
		return Object.class;
	}

	@Override
	public boolean isReadOnly(ELContext context, Object base, Object property) {
		return true;
	}

	@Override
	public Class<?> getType(ELContext context, Object base, Object property) {
		return null;
	}

	@Override
	public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
		return null;
	}
}